package com.boarsoft.boar.batch.demo;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.boarsoft.boar.batch.demo.biz.Coredpfm02Biz;
import com.boarsoft.boar.batch.demo.entity.Coredpfm02;
import com.boarsoft.boar.batch.demo.util.ToBigDecimal;
import com.boarsoft.common.util.RandomUtil;
import com.boarsoft.common.util.StreamUtil;
import com.boarsoft.flow.core.bean.ProcessHandler;

public class BigLoader02 implements ProcessHandler {
	private static final Logger log = LoggerFactory.getLogger(BigLoader02.class);

	private static final int BATCH_SIZE = 2000;

	@Autowired
	protected Coredpfm02Biz coredpfm02Biz;

	protected String fileName;

	protected ExecutorService threadPool = new ThreadPoolExecutor(//
			80, 80, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(80), Executors.defaultThreadFactory(),
			new ThreadPoolExecutor.CallerRunsPolicy());

	class SubSaver implements Runnable {
		int index;
		List<Coredpfm02> list;

		public SubSaver(int i, List<Coredpfm02> a) {
			index = i;
			list = a;
		}

		@Override
		public void run() {
			try {
				coredpfm02Biz.batchSave(index, list);
			} catch (SQLException e) {
				log.error("Error on batch save", e);
			}
		}
	}

	@Override
	public Object process(String entry, Object data, Throwable throwable) throws Throwable {
		Map<Integer, List<Coredpfm02>> map = new HashMap<Integer, List<Coredpfm02>>();
		for (int i = 0; i < 10; i++) {
			map.put(i, new ArrayList<Coredpfm02>());
		}
		File file = new File(fileName);
		BufferedInputStream bis = null;
		BufferedReader br = null;
		long l = System.currentTimeMillis();
		try {
			bis = new BufferedInputStream(new FileInputStream(file));
			br = new BufferedReader(new InputStreamReader(bis, "utf-8"), 8 * 1024 * 1024);
			String ln = null;
			while ((ln = br.readLine()) != null) {
				Coredpfm02 o = new Coredpfm02();
				try {
					this.parse(ln, o);
				} catch (Exception e) {
					log.error("Error on parse string:\n{}\n", ln, e);
					continue;
				}
				int i = Math.abs(o.getId().hashCode()) % 8;
				List<Coredpfm02> lt = map.get(i);
				lt.add(o);
				if (lt.size() >= BATCH_SIZE) {
					threadPool.execute(new SubSaver(i, lt));
					map.put(i, new ArrayList<Coredpfm02>());
				}
			}
			for (int i : map.keySet()) {
				List<Coredpfm02> lt = map.get(i);
				if (lt.isEmpty()) {
					continue;
				}
				threadPool.execute(new SubSaver(i, lt));
			}
			log.info("...............completed in {} minutes..............", //
					(System.currentTimeMillis() - l) / 1000 / 60);
		} catch (IOException e) {
			log.error("Error on read line from {}", fileName, e);
		} finally {
			// StreamUtil.close(bis);
			StreamUtil.close(br);
		}
		return true;
	}

	private void parse(String s, Coredpfm02 o) {
		String[] a = s.split("\03");
		o.setId(RandomUtil.randomUUID());
		o.setDM02ACCT(a[0]);
		o.setDM02ACCS(a[1]);
		o.setDM02ACCTYP(a[2]);
		o.setDM02HDFLG(a[3]);
		o.setDM02CLSFLG(a[4]);
		o.setDM02CCY(a[5]);
		o.setDM02CSHTRF(a[6]);
		o.setDM02PRDID(a[7]);
		o.setDM02SBNO(a[8]);
		o.setDM02OPNDAT(a[9]);
		o.setDM02STRDAT(a[10]);
		o.setDM02ENDDAT(a[11]);
		o.setDM02TERM1(ToBigDecimal.stringToBigDecimal(a[12]));
		o.setDM02TERM2(a[13]);
		o.setDM02BALE(ToBigDecimal.stringToBigDecimal(a[14]));
		o.setDM02BALD(a[15]);
		o.setDM02BALEN(ToBigDecimal.stringToBigDecimal(a[16]));
		o.setDM02EBALD(a[17]);
		o.setDM02LBALE(ToBigDecimal.stringToBigDecimal(a[18]));
		o.setDM02LBALD(a[19]);
		o.setDM02CTLBAL(ToBigDecimal.stringToBigDecimal(a[20]));
		o.setDM02FRZBAL(ToBigDecimal.stringToBigDecimal(a[21]));
		o.setDM02OVDBAL(ToBigDecimal.stringToBigDecimal(a[22]));
		o.setDM02CVDB1(ToBigDecimal.stringToBigDecimal(a[23]));
		o.setDM02CVDB2(ToBigDecimal.stringToBigDecimal(a[24]));
		o.setDM02CVDB3(ToBigDecimal.stringToBigDecimal(a[25]));
		o.setDM02ITPLAN(a[26]);
		o.setDM02ITFLT(ToBigDecimal.stringToBigDecimal(a[27]));
		o.setDM02LSTDTE(a[28]);
		o.setDM02NODE(a[29]);
		o.setDM02ACCCHR(a[30]);
		o.setDM02ACCCH1(a[31]);
		o.setDM02YZFLG(a[32]);
		o.setDM02TDUCTL(a[33]);
		o.setDM02CSHFLG(a[34]);
		o.setDM02ADVTIM(ToBigDecimal.stringToBigDecimal(a[35]));
		o.setDM02DMOD(a[36]);
		o.setDM02INTRAT(ToBigDecimal.stringToBigDecimal(a[37]));
		o.setDM02FRZFLG(a[38]);
		o.setDM02MRTFLG(a[39]);
		o.setDM02PRVFLG(a[40]);
		o.setDM02PBLIN(ToBigDecimal.stringToBigDecimal(a[41]));
		o.setDM02CVNFLG(a[42]);
		o.setDM02SECFLG(a[43]);
		o.setDM02OVDFLG(a[44]);
		o.setDM02IINFLG(ToBigDecimal.stringToLong(a[45]));
		o.setDM02INTFLG(ToBigDecimal.stringToLong(a[46]));
		o.setDM02INTFLG1(ToBigDecimal.stringToLong(a[47]));
		o.setDM02NRAMT(ToBigDecimal.stringToBigDecimal(a[47]));
		o.setDM02PMSAMT(ToBigDecimal.stringToBigDecimal(a[49]));
		o.setDM02INTPRD(ToBigDecimal.stringToBigDecimal(a[50]));
		o.setDM02DONTIM(ToBigDecimal.stringToBigDecimal(a[51]));
		o.setDM02NXDAT(a[52]);
		o.setDM02LZFLG(a[53]);
		o.setDM02LIEID(ToBigDecimal.stringToBigDecimal(a[54]));
		o.setDM02DTFLG(a[55]);
		o.setDM02ZCTIM(ToBigDecimal.stringToBigDecimal(a[56]));
		o.setDM02CONNO(a[57]);
		o.setDM02FEEFLG(a[58]);
		o.setDM02REMARK(a[59]);
		o.setDM02OLBAL(ToBigDecimal.stringToBigDecimal(a[60]));
		o.setDM02FLAG(a[61]);
		o.setDEL_F(ToBigDecimal.stringToLong(a[62]));
		o.setLAST_ETL_ACG_DT(a[63]);
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
}
